package com.tinyideatech.wechat.service;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.stereotype.Component;

import com.aliyuncs.utils.Base64Helper;

import lombok.extern.java.Log;

@Log
@Component
/*
 * 调试用ftp服务器，暂时废弃
 */
public class FtpService {

    private static final String FTP_URL = "123.206.46.177";
    private static final String FTP_USERNAME = "leo";
    private static final String FTP_PASSWORD = "12345";

    private FTPClient connectFtpServer() {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setConnectTimeout(1000 * 30);
        ftpClient.setControlEncoding("utf-8");
        ftpClient.enterLocalPassiveMode();
        try {

            ftpClient.connect(FTP_URL, 21);
            ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                log.info("connect ftp " + FTP_URL + " failed");
                ftpClient.disconnect();
                return null;
            }
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置文件传输模式为二进制，可以保证传输的内容不会被改变
            log.info("replyCode===========" + replyCode);
        } catch (IOException e) {
            log.info("connect fail ------->>>" + e.getCause());
            return null;
        }
        return ftpClient;
    }

    /**
     * @param inputStream 待上传文件的输入流
     * @param originName  文件保存时的名字
     */
    public void uploadFile(InputStream inputStream, String originName, String remoteDir) {
        FTPClient ftpClient = connectFtpServer();
        if (ftpClient == null) {
            return;
        }
        try {
            ftpClient.changeWorkingDirectory(remoteDir);// 进入到文件保存的目录
            Boolean isSuccess = ftpClient.storeFile(originName, inputStream);// 保存文件
            if (!isSuccess) {
                log.info("上传失败");
            } else {
                log.info(originName + "---》上传成功！");
            }
            ftpClient.logout();
        } catch (IOException e) {
            log.info("上传失败");
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    log.info("disconnect fail ------->>>" + e.getCause());
                }
            }
        }
    }

    /**
     * 读ftp上的文件，并将其转换成base64
     *
     * @param remoteFileName ftp服务器上的文件名
     * @return
     */
    public String readFileToBase64(String remoteFileName, String remoteDir) {
        FTPClient ftpClient = connectFtpServer();
        if (ftpClient == null) {
            return null;
        }
        String base64 = "";
        InputStream inputStream = null;
        try {
            ftpClient.changeWorkingDirectory(remoteDir);
            FTPFile[] ftpFiles = ftpClient.listFiles(remoteDir);
            Boolean flag = false;
            // 遍历当前目录下的文件，判断要读取的文件是否在当前目录下
            for (FTPFile ftpFile : ftpFiles) {
                if (ftpFile.getName().equals(remoteFileName)) {
                    flag = true;
                }
            }
            if (!flag) {
                log.info("directory：" + remoteDir + "下没有 " + remoteFileName);
                return null;
            }
            // 获取待读文件输入流
            inputStream = ftpClient.retrieveFileStream(remoteDir + remoteFileName);
            // inputStream.available() 获取返回在不阻塞的情况下能读取的字节数，正常情况是文件的大小
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);// 将文件数据读到字节数组中
            base64 = Base64Helper.encode(bytes);// 将字节数组转成base64字符串
            log.info("read file " + remoteFileName + " success");
            ftpClient.logout();
        } catch (IOException e) {
            log.info("read file fail ----->>>" + e.getCause());
            return null;
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    log.info("disconnect fail ------->>>" + e.getCause());
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.info("inputStream close fail -------- " + e.getCause());
                }
            }
        }
        return base64;

    }

    /**
     * 文件下载
     *
     * @param remoteFileName ftp上的文件名
     * @param localFileName  本地文件名
     */
    public void download(String remoteFileName, String localFileName, String remoteDir) {
        FTPClient ftpClient = connectFtpServer();
        if (ftpClient == null) {
            return;
        }
        OutputStream outputStream = null;
        try {
            ftpClient.changeWorkingDirectory(remoteDir);
            FTPFile[] ftpFiles = ftpClient.listFiles(remoteDir);
            Boolean flag = false;
            // 遍历当前目录下的文件，判断是否存在待下载的文件
            for (FTPFile ftpFile : ftpFiles) {
                if (ftpFile.getName().equals(remoteFileName)) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                return;
            }
            outputStream = new FileOutputStream("" + localFileName);// 创建文件输出流
            Boolean isSuccess = ftpClient.retrieveFile(remoteFileName, outputStream); // 下载文件
            if (isSuccess) {
                log.info("download file success");
            }

            ftpClient.logout();
        } catch (IOException e) {

        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                }
            }
        }
    }
}
